#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
use std::mem;
use crate::alloc_testing::*;
extern "C" {
        }
pub type size_t = libc::c_ulong;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _ListEntry {
    pub data: ListValue,
    pub prev: *mut ListEntry,
    pub next: *mut ListEntry,
}
pub type ListEntry = _ListEntry;
pub type ListValue = *mut libc::c_void;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _ListIterator {
    pub prev_next: *mut *mut ListEntry,
    pub current: *mut ListEntry,
}
pub type ListIterator = _ListIterator;
pub type ListCompareFunc = Option::<
    unsafe extern "C" fn(ListValue, ListValue) -> libc::c_int,
>;
pub type ListEqualFunc = Option::<
    unsafe extern "C" fn(ListValue, ListValue) -> libc::c_int,
>;
#[no_mangle]
pub extern "C" fn list_free(mut list: *mut ListEntry) {
    let mut entry: *mut ListEntry = list;
    while !entry.is_null() {
        let next: *mut ListEntry;
        let boxed_entry = unsafe { Box::from_raw(entry) };
        next = boxed_entry.next;
        alloc_test_free(entry as *mut libc::c_void);
        entry = next;
        let _ = Box::into_raw(boxed_entry);
    }
}
#[no_mangle]
pub extern "C" fn list_prepend(
    mut list: *mut *mut ListEntry,
    mut data: ListValue,
) -> *mut ListEntry {
    let mut newentry: *mut ListEntry = std::ptr::null_mut();

    if list.is_null() {
        return std::ptr::null_mut();
    }

    
    unsafe {
        newentry = alloc_test_malloc(std::mem::size_of::<ListEntry>() as libc::c_ulong)
            as *mut ListEntry;
    }

    if newentry.is_null() {
        return std::ptr::null_mut();
    }

    
    unsafe {
        (*newentry).data = data;
        if !(*list).is_null() {
            (**list).prev = newentry;
        }
        (*newentry).prev = std::ptr::null_mut();
        (*newentry).next = *list;
        *list = newentry;
    }

    newentry
}
#[no_mangle]
pub extern "C" fn list_append(
    mut list: *mut *mut ListEntry,
    mut data: ListValue,
) -> *mut ListEntry {
    let mut rover: *mut ListEntry = std::ptr::null_mut();
    let mut newentry: *mut ListEntry = std::ptr::null_mut();

    if list.is_null() {
        return std::ptr::null_mut();
    }

    newentry = unsafe {
        alloc_test_malloc(std::mem::size_of::<ListEntry>() as libc::c_ulong) as *mut ListEntry
    };

    if newentry.is_null() {
        return std::ptr::null_mut();
    }

    let mut boxed_newentry = unsafe { Box::from_raw(newentry) };
    boxed_newentry.data = data;
    boxed_newentry.next = std::ptr::null_mut();
    newentry = Box::into_raw(boxed_newentry);

    if unsafe { (*list).is_null() } {
        unsafe {
            *list = newentry;
            (*newentry).prev = std::ptr::null_mut();
        }
    } else {
        rover = unsafe { *list };
        while !unsafe { (*rover).next }.is_null() {
            rover = unsafe { (*rover).next };
        }
        unsafe {
            (*newentry).prev = rover;
            (*rover).next = newentry;
        }
    }

    return newentry;
}
#[no_mangle]
pub extern "C" fn list_data(mut listentry: *mut ListEntry) -> ListValue {
    if listentry.is_null() {
        return 0 as *mut libc::c_void;
    }
    let boxed_listentry = unsafe { Box::from_raw(listentry) };
    let data = boxed_listentry.data;
    let listentry = Box::into_raw(boxed_listentry);
    data
}
#[no_mangle]
pub extern "C" fn list_set_data(
    mut listentry: *mut ListEntry,
    mut value: ListValue,
) {
    if !listentry.is_null() {
        let mut boxed_listentry = unsafe { Box::from_raw(listentry) };
        boxed_listentry.data = value;
        listentry = Box::into_raw(boxed_listentry);
    }
}
#[no_mangle]
pub extern "C" fn list_prev(mut listentry: *mut ListEntry) -> *mut ListEntry {
    if listentry.is_null() {
        return std::ptr::null_mut();
    }
    
    let boxed_listentry = unsafe { Box::from_raw(listentry) };
    let prev = boxed_listentry.prev;
    let listentry = Box::into_raw(boxed_listentry);
    prev
}
#[no_mangle]
pub extern "C" fn list_next(mut listentry: *mut ListEntry) -> *mut ListEntry {
    if listentry.is_null() {
        return std::ptr::null_mut();
    }
    
    let boxed_listentry = unsafe { Box::from_raw(listentry) };
    let next = boxed_listentry.next;
    let listentry = Box::into_raw(boxed_listentry);
    next
}
#[no_mangle]
pub extern "C" fn list_nth_entry(
    mut list: *mut ListEntry,
    mut n: libc::c_uint,
) -> *mut ListEntry {
    let mut entry: *mut ListEntry = std::ptr::null_mut();
    let mut i: libc::c_uint = 0;

    unsafe {
        entry = list;
    }

    while i < n {
        if entry.is_null() {
            return std::ptr::null_mut();
        }
        
        let boxed_entry = unsafe { Box::from_raw(entry) };
        entry = boxed_entry.next;
        let entry = Box::into_raw(boxed_entry);
        i = i.wrapping_add(1);
    }

    entry
}
#[no_mangle]
pub extern "C" fn list_nth_data(
    mut list: *mut ListEntry,
    mut n: libc::c_uint,
) -> ListValue {
    let mut entry: *mut ListEntry = std::ptr::null_mut();

    unsafe {
        entry = list_nth_entry(list, n);
    }

    if entry.is_null() {
        return 0 as *mut libc::c_void;
    } else {
        let boxed_entry = unsafe { Box::from_raw(entry) };
        let data = boxed_entry.data;
        let entry = Box::into_raw(boxed_entry);
        return data;
    }
}
#[no_mangle]
pub extern "C" fn list_length(mut list: *mut ListEntry) -> libc::c_uint {
    let mut entry: *mut ListEntry = list;
    let mut length: libc::c_uint = 0;

    while !entry.is_null() {
        length = length.wrapping_add(1);
        entry = unsafe { (*entry).next };
    }

    length
}
#[no_mangle]
pub extern "C" fn list_to_array(mut list: *mut ListEntry) -> *mut ListValue {
    let mut rover: *mut ListEntry = std::ptr::null_mut();
    let mut array: *mut ListValue = std::ptr::null_mut();
    let mut length: libc::c_uint = 0;
    let mut i: libc::c_uint = 0;

    length = list_length(list);
    array = unsafe {
        alloc_test_malloc(
            (std::mem::size_of::<ListValue>() as libc::c_ulong)
                .wrapping_mul(length as libc::c_ulong),
        ) as *mut ListValue
    };

    if array.is_null() {
        return std::ptr::null_mut();
    }

    rover = list;
    i = 0;

    unsafe {
        while i < length {
            let ref mut fresh0 = *array.offset(i as isize);
            *fresh0 = (*rover).data;
            rover = (*rover).next;
            i = i.wrapping_add(1);
        }
    }

    array
}
#[no_mangle]
pub extern "C" fn list_remove_entry(
    mut list: *mut *mut ListEntry,
    mut entry: *mut ListEntry,
) -> libc::c_int {
    if list.is_null() || unsafe { (*list).is_null() } || entry.is_null() {
        return 0;
    }

    let mut boxed_entry = unsafe { Box::from_raw(entry) };
    let mut boxed_list = unsafe { Box::from_raw(list) };

    if boxed_entry.prev.is_null() {
        *boxed_list = boxed_entry.next;
        if !boxed_entry.next.is_null() {
            let mut boxed_next = unsafe { Box::from_raw(boxed_entry.next) };
            boxed_next.prev = std::ptr::null_mut();
            boxed_entry.next = Box::into_raw(boxed_next);
        }
    } else {
        let mut boxed_prev = unsafe { Box::from_raw(boxed_entry.prev) };
        boxed_prev.next = boxed_entry.next;
        boxed_entry.prev = Box::into_raw(boxed_prev);
        if !boxed_entry.next.is_null() {
            let mut boxed_next = unsafe { Box::from_raw(boxed_entry.next) };
            boxed_next.prev = boxed_entry.prev;
            boxed_entry.next = Box::into_raw(boxed_next);
        }
    }

    alloc_test_free(entry as *mut libc::c_void);
    list = Box::into_raw(boxed_list);
    entry = Box::into_raw(boxed_entry);
    return 1;
}
#[no_mangle]
pub extern "C" fn list_remove_data(
    mut list: *mut *mut ListEntry,
    mut callback: ListEqualFunc,
    mut data: ListValue,
) -> libc::c_uint {
    let mut entries_removed: libc::c_uint = 0;
    let mut rover: *mut ListEntry = std::ptr::null_mut();
    let mut next: *mut ListEntry = std::ptr::null_mut();

    if list.is_null() || callback.is_none() {
        return 0;
    }

    entries_removed = 0;

    unsafe {
        rover = *list;

        while !rover.is_null() {
            next = (*rover).next;

            if callback.expect("non-null function pointer")((*rover).data, data) != 0 {
                if (*rover).prev.is_null() {
                    *list = (*rover).next;
                } else {
                    (*(*rover).prev).next = (*rover).next;
                }

                if !(*rover).next.is_null() {
                    (*(*rover).next).prev = (*rover).prev;
                }

                alloc_test_free(rover as *mut libc::c_void);
                entries_removed = entries_removed.wrapping_add(1);
            }

            rover = next;
        }
    }

    entries_removed
}
extern "C" fn list_sort_internal(
    mut list: *mut *mut ListEntry,
    mut compare_func: ListCompareFunc,
) -> *mut ListEntry {
    let mut pivot: *mut ListEntry = std::ptr::null_mut();
    let mut rover: *mut ListEntry = std::ptr::null_mut();
    let mut less_list: *mut ListEntry = std::ptr::null_mut();
    let mut more_list: *mut ListEntry = std::ptr::null_mut();
    let mut less_list_end: *mut ListEntry = std::ptr::null_mut();
    let mut more_list_end: *mut ListEntry = std::ptr::null_mut();

    if list.is_null() || compare_func.is_none() {
        return std::ptr::null_mut();
    }

    unsafe {
        if (*list).is_null() || ((**list).next).is_null() {
            return *list;
        }

        pivot = *list;
        less_list = std::ptr::null_mut();
        more_list = std::ptr::null_mut();
        rover = (**list).next;

        while !rover.is_null() {
            let next: *mut ListEntry = (*rover).next;
            if compare_func.expect("non-null function pointer")((*rover).data, (*pivot).data) < 0 {
                (*rover).prev = std::ptr::null_mut();
                (*rover).next = less_list;
                if !less_list.is_null() {
                    (*less_list).prev = rover;
                }
                less_list = rover;
            } else {
                (*rover).prev = std::ptr::null_mut();
                (*rover).next = more_list;
                if !more_list.is_null() {
                    (*more_list).prev = rover;
                }
                more_list = rover;
            }
            rover = next;
        }
    }

    less_list_end = list_sort_internal(&mut less_list, compare_func);
    more_list_end = list_sort_internal(&mut more_list, compare_func);

    unsafe {
        *list = less_list;
        if less_list.is_null() {
            (*pivot).prev = std::ptr::null_mut();
            *list = pivot;
        } else {
            (*pivot).prev = less_list_end;
            (*less_list_end).next = pivot;
        }
        (*pivot).next = more_list;
        if !more_list.is_null() {
            (*more_list).prev = pivot;
        }
    }

    if more_list.is_null() {
        pivot
    } else {
        more_list_end
    }
}
#[no_mangle]
pub extern "C" fn list_sort(
    mut list: *mut *mut ListEntry,
    mut compare_func: ListCompareFunc,
) {
    unsafe {
        list_sort_internal(list, compare_func);
    }
}
#[no_mangle]
pub extern "C" fn list_find_data(
    mut list: *mut ListEntry,
    mut callback: ListEqualFunc,
    mut data: ListValue,
) -> *mut ListEntry {
    let mut rover: *mut ListEntry = list;
    while !rover.is_null() {
        if unsafe { callback.expect("non-null function pointer")((*rover).data, data) } != 0 {
            return rover;
        }
        rover = unsafe { (*rover).next };
    }
    return std::ptr::null_mut();
}
#[no_mangle]
pub extern "C" fn list_iterate(
    mut list: *mut *mut ListEntry,
    mut iter: *mut ListIterator,
) {
    let mut boxed_iter = unsafe { Box::from_raw(iter) };
    boxed_iter.prev_next = list;
    boxed_iter.current = std::ptr::null_mut();
    let iter = Box::into_raw(boxed_iter);
}
#[no_mangle]
pub extern "C" fn list_iter_has_more(mut iter: *mut ListIterator) -> libc::c_int {
    let boxed_iter = unsafe { Box::from_raw(iter) };
    let result = unsafe {
        if boxed_iter.current.is_null() || boxed_iter.current != *boxed_iter.prev_next {
            (*boxed_iter.prev_next != std::ptr::null_mut()) as libc::c_int
        } else {
            ((*boxed_iter.current).next != std::ptr::null_mut()) as libc::c_int
        }
    };
    iter = Box::into_raw(boxed_iter);
    result
}
#[no_mangle]
pub extern "C" fn list_iter_next(mut iter: *mut ListIterator) -> ListValue {
    let mut boxed_iter = unsafe { Box::from_raw(iter) };
    let result = unsafe {
        if boxed_iter.current.is_null() || boxed_iter.current != *boxed_iter.prev_next {
            boxed_iter.current = *boxed_iter.prev_next;
        } else {
            boxed_iter.prev_next = &mut (*boxed_iter.current).next;
            boxed_iter.current = (*boxed_iter.current).next;
        }

        if boxed_iter.current.is_null() {
            0 as *mut libc::c_void
        } else {
            (*boxed_iter.current).data
        }
    };
    iter = Box::into_raw(boxed_iter);
    result
}
#[no_mangle]
pub extern "C" fn list_iter_remove(mut iter: *mut ListIterator) {
    if !iter.is_null() {
        let mut boxed_iter = unsafe { Box::from_raw(iter) };
        if !boxed_iter.current.is_null() && boxed_iter.current == unsafe { *boxed_iter.prev_next } {
            let current = boxed_iter.current;
            unsafe {
                *boxed_iter.prev_next = (*current).next;
                if !(*current).next.is_null() {
                    (*(*current).next).prev = (*current).prev;
                }
                alloc_test_free(current as *mut libc::c_void);
            }
            boxed_iter.current = std::ptr::null_mut();
        }
        iter = Box::into_raw(boxed_iter);
    }
}
